/*
 * @Author: yayalee yangcheng960813@163.com
 * @Date: 2024-07-15 09:13:55
 * @LastEditTime: 2024-07-15 09:23:34
 * @LastEditors: yayalee yangcheng960813@163.com
 * @Description: 
 * @FilePath: \unfinished-challenges\assets\core_cc\node\node.ts
 * 可以输入预定的版权声明、个性签名、空行等
 */
/*
* @ Author: yangcheng
* @ Data: 2024-07-15 09:13
*/

import { Button, Component, Label, Node, ProgressBar, RichText, Sprite, SpriteFrame, Texture2D, UITransform, js } from "cc";
import { DEV, EDITOR } from "cc/env";
import { _cc } from "../_cc";

const tag = "警告: ";

/**检查这个节点是否是有效的 */
const nodeCheckIsValid = function (obj: any, componentName: string) {
    //@ts-ignore
    let that = this;
    if (!obj) {
        console.warn(`${tag} 节点 ${that.name} 没有这个 ${componentName} 组件`)
    }
    return obj;
};
/**获得组件脚本的名字 */
const componentName = DEV ? function () {
    //@ts-ignore
    let that = this;
    return that.constructor.name + "-Component";
} : function () {
    //@ts-ignore
    let that = this;
    return js.getClassName(that) + "-Component";
};
/**获取节点的名字 */
const nodeName = function () {
    //@ts-ignore
    let that = this;
    return that.name + "-Node";
}

// Editro 模式下 不走这代码 不然 每次编译在 编辑器里都会有报错提示 烦得很
if (!EDITOR) {

    Object.defineProperty(Node.prototype, "childCount", {
        get: function () {
            return this.children.length;
        },
    });

    //#region Node Size
    //-------------------------------------------------------------------------------
    Object.defineProperty(Node.prototype, "w", {
        get: function () {
            return this.uiTransform?.width;
        },
        set: function (v) {
            const { width, height } = this.uiTransform ?? {};
            this.uiTransform?.setContentSize(v, height);
            // this.uiTransform.width = v;
        }
    });
    Object.defineProperty(Node.prototype, "h", {
        get: function () {
            return this.uiTransform?.height;
        },
        set: function (v) {
            const { width, height } = this.uiTransform ?? {};
            this.uiTransform?.setContentSize(width, v);
            // this.uiTransform.height = v;
        }
    });

    //#endregion

    //#region Node Position
    //-------------------------------------------------------------------------------
    Object.defineProperty(Node.prototype, "x", {
        get: function () {
            return this.position.x;
        },
        set: function (v) {
            _cc.setPos(this, v);
        }
    });
    Object.defineProperty(Node.prototype, "y", {
        get: function () {
            return this.position.y;
        },
        set: function (v) {
            _cc.setPos(this, this.position.x, v);
        }
    });
    Object.defineProperty(Node.prototype, "z", {
        get: function () {
            return this.position.y;
        },
        set: function (v) {
            _cc.setPos(this, this.position.x, this.position.y, v);
        }
    });
    //#endregion

    //#region UI
    //-------------------------------------------------------------------------------
    Object.defineProperty(Node.prototype, "label", {
        get: function () {
            if (!this.$label) this.$label = this.getComponent(Label);
            return this.$label;
        }
    });
    Object.defineProperty(Node.prototype, "richText", {
        get: function () {
            if (!this.$richText) this.$richText = this.getComponent(RichText);
            return this.$richText;
        }
    });
    Object.defineProperty(Node.prototype, "progressBar", {
        get: function () {
            if (!this.$progressBar) this.$progressBar = this.getComponent(ProgressBar);
            return this.$progressBar;
        }
    });
    Object.defineProperty(Node.prototype, "sprite", {
        get: function () {
            if (!this.$sprite) this.$sprite = this.getComponent(Sprite);
            return this.$sprite;
        }
    });
    Object.defineProperty(Node.prototype, "button", {
        get: function () {
            if (!this.$button) this.$button = this.getComponent(Button);
            return this.$button;
        },
        set: function (v) {
            this.$button = v;
        }
    });
    Object.defineProperty(Node.prototype, "uiTransform", {
        get: function () {
            if (!this.$uiTransform) this.$uiTransform = this.getComponent(UITransform);
            return this.$uiTransform;
        }
    });
    Object.defineProperty(Component.prototype, "uiTransform", {
        get: function () {
            return this.node.uiTransform;
        },
    });
    //#endregion
}
//@ts-ignore
Node.prototype.$ = function (target: number | string | any = 0, inChildrenSearch = false) {
    /**节点下标 */
    if (isNumber(target)) {
        return this.children[target];
    }
    /*节点*/
    if (isString(target)) {
        return _cc.find(target as any, this);
    }
    /*组件*/
    if (!inChildrenSearch) {
        return this.getComponent(target);
    }
    return this.getComponentInChildren(target);
};

Node.prototype.show = function () {
    return this.active = true;
};

Node.prototype.hide = function () {
    return this.active = false;
};
Node.prototype.showAllChildren = function () {
    forEach(this.children, (node: Node) => {
        node && node.show();
    })
}
Node.prototype.hideAllChildren = function () {
    forEach(this.children, (node: Node) => {
        node && node.hide();
    })
};


Node.prototype.setLabel = function (str: string) {
    if (nodeCheckIsValid.apply(this, [this.label, "Label"]))
        this.label.string = str;
};

Node.prototype.setRichText = function (str: string) {
    if (nodeCheckIsValid.apply(this, [this.richText, "RichText"]))
        this.richText.string = str;
};

Node.prototype.setProgress = function (value) {
    if (nodeCheckIsValid.apply(this, [this.progressBar, "ProgressBar"]))
        this.progressBar.progress = value;
};

Node.prototype.setSpriteFrame = function (sp: SpriteFrame) {
    if (nodeCheckIsValid.apply(this, [this.sprite, "Sprite"])) {
        //功能有待测试
        if (sp instanceof Texture2D) {
            var spf = new SpriteFrame();
            spf.texture = sp;
            sp = spf;
        }
        this.sprite.spriteFrame = sp;
    }
};

Node.prototype.click = function (func, that) {
    _cc.click(this, func, that);
    //@ts-ignore
    // if (!this.button) this.button = this.addComponent(Button)!;
    // (this.button as Button).transition = Button.Transition.SCALE;
};

Node.prototype.$click = function (func, that) {
    _cc.$click(this, func, that);
    // (this.button as Button).transition = Button.Transition.NONE;
};

//#region Node Component LogInfo
//-------------------------------------------------------------------------------
// Node.prototype.debug = function (...args: any) {
//     _log.debug(nodeName.apply(this), ...args);
// };
// Node.prototype.info = function (...args: any) {
//     _log.info(nodeName.apply(this), ...args);
// };
// Node.prototype.warn = function (...args: any) {
//     _log.warn(nodeName.apply(this), ...args);
// };
// Node.prototype.error = function (...args: any) {
//     _log.error(nodeName.apply(this), ...args);
// };
// Node.prototype.fatal = function (...args: any) {
//     _log.fatal(nodeName.apply(this), ...args);
// };
// Node.prototype.log = function (...args: any) {
//     _log.log(...args);
// };
// Node.prototype.logs = function (title: string, msg: string) {
//     _log.logs(title, msg);
// };
// Node.prototype.time = function (label?: string) {
//     _log.time(label);
// }
// Node.prototype.timeEnd = function (label?: string) {
//     _log.timeEnd(label);
// }
//-------------------------------------------------------------------------------
// Component.prototype.debug = function (...args: any) {
//     _log.debug(componentName.apply(this), ...args);
// };
// Component.prototype.info = function (...args: any) {
//     _log.info(componentName.apply(this), ...args);
// };
// Component.prototype.warn = function (...args: any) {
//     _log.warn(componentName.apply(this), ...args);
// };
// Component.prototype.error = function (...args: any) {
//     _log.error(componentName.apply(this), ...args);
// };
// Component.prototype.fatal = function (...args: any) {
//     _log.fatal(componentName.apply(this), ...args);
// };
// Component.prototype.log = function (...args: any) {
//     _log.log(args);
// };
// Component.prototype.logs = function (title: string, msg: string) {
//     _log.logs(title, msg);
// };
// Component.prototype.time = function (label?: string) {
//     _log.time(label);
// };
// Component.prototype.timeEnd = function (label?: string) {
//     _log.timeEnd(label);
// };
Component.prototype.waitCmpt = function (seconds: number = 0) {
    return _cc.waitCmpt(this, seconds);
};
//-------------------------------------------------------------------------------
//#endregion